package com.magist.manage.copyrights.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jeesuite.common.util.DateUtils;
import com.magist.core.entity.CxtHolder;
import com.magist.core.entity.Page;
import com.magist.core.entity.ResultMessage;
import com.magist.core.exception.BusinessException;
import com.magist.core.service.SimpleServiceImpl;
import com.magist.core.util.BeanCompareUtil;
import com.magist.core.util.BeanCopyUtil;
import com.magist.core.util.DateUtil;
import com.magist.core.util.EnumOrderUtil;
import com.magist.core.util.MAssertUtil;
import com.magist.core.util.ObjectCheckUtil;
import com.magist.manage.constant.BusinessCodeConstant;
import com.magist.manage.copyrights.dao.CopyrightsMapper;
import com.magist.manage.copyrights.dto.ContractRightsDto;
import com.magist.manage.copyrights.dto.CopyrightsDto;
import com.magist.manage.copyrights.entity.ContractRights;
import com.magist.manage.copyrights.entity.Copyrights;
import com.magist.manage.copyrights.entity.SupplyContract;
import com.magist.manage.copyrights.service.ContractRightsService;
import com.magist.manage.copyrights.service.CopyrightsService;
import com.magist.manage.copyrights.service.SupplyContractService;
import com.magist.manage.enums.BackgroundEnum;
import com.magist.manage.enums.BalanceTypeEnum;
import com.magist.manage.enums.CopyrightClassEnum;
import com.magist.manage.enums.CopyrightsRangeEnum;
import com.magist.manage.enums.OnlineStatusEnum;
import com.magist.manage.enums.OpActionEnum;
import com.magist.manage.enums.OpTypeEnum;
import com.magist.manage.enums.TFEnum;
import com.magist.manage.enums.UsedPlatformEnum;
import com.magist.manage.enums.ValidStatusEnum;
import com.magist.manage.enums.WorksTypeEnum;
import com.magist.manage.util.BusinessCodeGenter;
import com.magist.manage.util.BusinessLogUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

@Service
public class CopyrightsServiceImpl extends SimpleServiceImpl<Copyrights> implements CopyrightsService{

	@Autowired
	private CopyrightsMapper copyrightsMapper;
	@Autowired
	private SupplyContractService supplyContractService;

	@Autowired
	private BusinessCodeGenter businessCodeGenter;
	@Autowired
	private ContractRightsService contractRightsService;
	@Autowired
	private BusinessLogUtil businessLogUtil;


	@Override
	public PageInfo<Copyrights> page(Example example, Page page) {
		String orderBy = page.getSort() + " " + page.getOrder();
		if(StringUtils.isEmpty(orderBy.trim())) {
			PageHelper.startPage(page.getCurrPage(), page.getLimit());
		} else {
			PageHelper.startPage(page.getCurrPage(), page.getLimit(),orderBy);
		}
    	List<Copyrights> list = this.find(example);
        PageInfo<Copyrights> pageInfo = new PageInfo(list);
		return pageInfo;
	}

	@Override
	public void addCopyRights(CopyrightsDto copyrightsDto) {
		copyrightsDto.setWorksStatus(ValidStatusEnum.VALID.getCode());
		// 校验参数
		this.check(copyrightsDto);
		this.doInsertContract(copyrightsDto);
	}

	@Override
	public int updateCopyrights(CopyrightsDto copyrightsDto) {
		// 校验参数
		this.check(copyrightsDto);

		String id = copyrightsDto.getId();
		MAssertUtil.notNull(id,"授权更新操作主键不能为空");

		Copyrights oldCopyrights = this.getById(id);
		CopyrightsDto oldDto = BeanCopyUtil.copy(oldCopyrights, CopyrightsDto.class);
		String worksStatus = oldCopyrights.getWorksStatus();
		if (ValidStatusEnum.INVALID.getCode().equals(worksStatus))
			throw new BusinessException("失效版权不允许修改");
		Copyrights copyrights = new Copyrights();
		BeanUtils.copyProperties(copyrightsDto,copyrights);
		copyrights.setModifyTime(oldCopyrights.getModifyTime());


		int update = this.update(copyrights);

		try {
			String compare = BeanCompareUtil.compare(oldDto, copyrightsDto);
			businessLogUtil.recordBusinessLog(OpActionEnum.EDIT.getCode(),OpTypeEnum.Copyrights.getCode(),copyrights.getId(),"修改授权:" + copyrights.getCopyrightsNo(),compare);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return update;
	}

	private void check(CopyrightsDto copyrightsDto) {
		this.commonCheck(copyrightsDto);
		MAssertUtil.notNull(copyrightsDto.getSupplyId(),"请填写供应商主键");
	}

	/**
	 * 通用的参数校验,为了excel导入也能复用这个方法
	 * 主要是判空和字段长度校验
	 * @param copyrightsDto
	 */
	private void commonCheck(CopyrightsDto copyrightsDto) {
		MAssertUtil.notNull(copyrightsDto.getWorksName(),"请填写作品名称");
		MAssertUtil.notNull(copyrightsDto.getContentStatus(),"请填写内容状况");
		MAssertUtil.notNull(copyrightsDto.getContractNo(),"请填写合同编号");
		MAssertUtil.notNull(copyrightsDto.getCopyrightClass(),"请填写版权权利");
		MAssertUtil.notNull(copyrightsDto.getSoleFlag(),"请填写是否独家授权");
		MAssertUtil.notNull(copyrightsDto.getSubRightsFlag(),"请填写有无转授权");
		MAssertUtil.notNull(copyrightsDto.getProtocolFlag(),"请填写有无补充协议");
		MAssertUtil.notNull(copyrightsDto.getBeginDate(),"请填写开始时间");
		MAssertUtil.notNull(copyrightsDto.getEndDate(),"请填写终止时间");
		MAssertUtil.notNull(copyrightsDto.getCopyrightsRange(),"请填写权限使用范围");
		MAssertUtil.notNull(copyrightsDto.getUsedPlatform(),"请填写使用平台");
		MAssertUtil.notNull(copyrightsDto.getOriginalCopyrightsFlag(),"请填写原始版权");
		MAssertUtil.notNull(copyrightsDto.getBalanceType(),"请填写结算形式");

		MAssertUtil.notNull(copyrightsDto.getOnlineStatus(),"请填写上线状态");

		// 长度校验
		MAssertUtil.shorterThan(copyrightsDto.getWorksName(),31,"作品名称超过30个字");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getPublishingName(),31,"出版社超过30个字");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getAuthorName(),31,"文字作者超过30个字");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getPictureAuthorName(),31,"绘者超过30个字");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getTranslatorName(),31,"译者超过30个字");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getSeriesName(),31,"系列名称超过30个字");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getAnchorName(),31,"主播超过30个字");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getWorksIntroduction(),801,"作品简介超过800个字");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getAuthorIntroduction(),801,"作者简介超过800个字");
		if(!ObjectUtils.isEmpty(copyrightsDto.getSeriesNum())) {
			MAssertUtil.nullOrShorterThan(copyrightsDto.getSeriesNum().toString(),11,"集数输入过长");
		}
		MAssertUtil.nullOrShorterThan(copyrightsDto.getIsbnNo(),61,"ISBN号长度过长");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getPublishingName(),31,"出版社长度超过30个字符");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getRemark(),501,"备注过长");
		MAssertUtil.nullOrShorterThan(copyrightsDto.getBalanceRemark(),501,"结算说明过长");

		// 判断时间
		if (copyrightsDto.getBeginDate().after(copyrightsDto.getEndDate())) {
			throw new BusinessException("开始时间不能晚于结束时间");
		}

		// 判断合同是否存在并生效
		SupplyContract supplyContract = supplyContractService.findByContractNo(copyrightsDto.getContractNo());
		MAssertUtil.notNull(supplyContract,"合同不存在");
		String contractStatus = supplyContract.getContractStatus();
		if (!ValidStatusEnum.VALID.getCode().equals(contractStatus)) {
			throw new BusinessException("合同已失效");
		}
		// 根据合同判断
		String balanceType = copyrightsDto.getBalanceType();
		if (!BalanceTypeEnum.BUY.getCode().equals(balanceType)) {
			MAssertUtil.notNull(copyrightsDto.getPartyOneNum(),"结算方式非买断,请填写甲方比例");
			MAssertUtil.notNull(copyrightsDto.getPartyTwoNum(),"结算方式非买断,请填写乙方比例");
			Integer contractNum = supplyContract.getContractNum();
			if (contractNum.equals(3)) {
				MAssertUtil.notNull(copyrightsDto.getPartyThreeNum(),"结算方式非买断且两方合同,请填写丙方比例");
			}

		}

		if (!BalanceTypeEnum.DIVIDE.getCode().equals(balanceType)) {
			MAssertUtil.notNull(copyrightsDto.getBalance(),"请填写金额");
			MAssertUtil.shorterThan(copyrightsDto.getBalance().toString() , 11, "金额输入过长");
		}



		// 供应商id从合同中取
		String supplyId = supplyContract.getSupplyId();
		copyrightsDto.setSupplyId(supplyId);
		this.checkDataDup(copyrightsDto.getId(), copyrightsDto.getWorksName(), copyrightsDto.getContractNo());


		// 纠正多选排序
        copyrightsDto.setBackground(EnumOrderUtil.orderEnum(BackgroundEnum.values(), copyrightsDto.getBackground()));
        copyrightsDto.setCopyrightClass(EnumOrderUtil.orderEnum(CopyrightClassEnum.values(), copyrightsDto.getCopyrightClass()));
        copyrightsDto.setCopyrightsRange(EnumOrderUtil.orderEnum(CopyrightsRangeEnum.values(), copyrightsDto.getCopyrightsRange()));
        copyrightsDto.setUsedPlatform(EnumOrderUtil.orderEnum(UsedPlatformEnum.values(), copyrightsDto.getUsedPlatform()));
	}

	@Override
	public void doInvalidByContractId(String contractId) {
		SupplyContract supplyContract = supplyContractService.getById(contractId);
		if(ObjectUtils.isEmpty(supplyContract)) {
			return;
		}
		String contractNo = supplyContract.getContractNo();
		if(StringUtils.isEmpty(contractNo)) {
			return;
		}
		List<Copyrights> copyrights = this.findByContractNo(contractNo);
		if (CollectionUtils.isEmpty(copyrights)) {
			return;
		}


		copyrights.forEach(copyrights1 -> {
			if (ValidStatusEnum.VALID.getCode().equals(copyrights1.getWorksStatus())) {
				copyrights1.setWorksStatus(ValidStatusEnum.INVALID.getCode());
				try {
					// 添加操作日志
					businessLogUtil.recordBusinessLog(OpActionEnum.INVALID.getCode(),OpTypeEnum.Copyrights.getCode(), copyrights1.getId(), "关联失效版权:" + copyrights1.getCopyrightsNo(), "失效合同:" + supplyContract.getContractNo() + ",关联失效版权:" + copyrights1.getCopyrightsNo()+";状态:[已生效]改成[已失效];");
				} catch (Exception e) {
					e.printStackTrace();
				}

				this.update(copyrights1);
			}
		});
	}

	@Override
	public List<Copyrights> findByContractNo(String contractNo) {
		Example example = new Example(Copyrights.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("deleted", "F");
		criteria.andEqualTo("contractNo", contractNo);
		return this.find(example);
	}

	@Override
	public int doInvalidCopyrights(String id) {
		Copyrights copyrights = this.getById(id);
		if(ObjectUtils.isEmpty(copyrights)) {
			throw new BusinessException("查询不到版权");
		}
		int update = 0;
		if (ValidStatusEnum.VALID.getCode().equals(copyrights.getWorksStatus())) {
			copyrights.setWorksStatus(ValidStatusEnum.INVALID.getCode());

			List<ContractRights> contractRights = contractRightsService.findByContractNoAndStatus(copyrights.getContractNo(), ValidStatusEnum.VALID.getCode());
			StringBuilder opContent = new StringBuilder();
			if (!CollectionUtils.isEmpty(contractRights)) {
				opContent.append("关联失效授权:");
				for (ContractRights contractRight : contractRights) {
					opContent.append(contractRight.getContractRightsNo() + ",");
				}
			}

			try {
				businessLogUtil.recordBusinessLog(OpActionEnum.INVALID.getCode(),OpTypeEnum.Copyrights.getCode(), id, "失效版权:" + copyrights.getCopyrightsNo(), "失效版权:" + copyrights.getCopyrightsNo()+";状态:[已生效]改成[已失效];"+opContent.toString());
			} catch (Exception e) {
				e.printStackTrace();
			}

			contractRightsService.doInvalidByCopyrightsId(id);
			update = this.update(copyrights);
		}

		return update;
	}

	@Override
	public Copyrights findByCopyrightsNo(String copyrightsNo) {
		if(StringUtils.isEmpty(copyrightsNo)) {
			return null;
		}
		Copyrights copyrights = new Copyrights();
		copyrights.setCopyrightsNo(copyrightsNo);
		List<Copyrights> copyrightses = this.find(copyrights);
		if (!CollectionUtils.isEmpty(copyrightses)) {
			return copyrightses.get(0);
		}
		return null;
	}

	@Override
	public void doBatchAdd(List<CopyrightsDto> copyrightsDtos) {
		//约定作品名称、合同编号
		List<String> checkDup = new LinkedList<>();
		for (int i = 0; i < copyrightsDtos.size(); i++) {
			CopyrightsDto copyrightsDto = copyrightsDtos.get(i);
			if(ObjectCheckUtil.isAllFieldNull(copyrightsDto)) {
				copyrightsDtos.remove(copyrightsDto);
				i--;
				continue;
			}
			try {
				this.checkImport(copyrightsDto);
				// 合同编号和合作供应商联合为防重复
				String worksName = copyrightsDto.getWorksName();
				String contractNo = copyrightsDto.getContractNo();
				String mix = worksName + contractNo;
				if(checkDup.contains(mix)) {
					throw new BusinessException("数据重复,已存在该合同编号和合作供应商组合的版权");
				} else {
					checkDup.add(mix);
				}
			} catch (Exception e) {
				throw new BusinessException("第" + (i + 1) + "条数据错误," + e.getMessage());
			}
		}
		businessLogUtil.recordBusinessLog(OpActionEnum.IMPORT.getCode(),Copyrights.class.getSimpleName(),null,"导入版权开始","批量导入版权开始,需导入" + copyrightsDtos.size()+"条记录");
		copyrightsDtos.forEach(copyrightsDto->this.doInsertContract(copyrightsDto));
		businessLogUtil.recordBusinessLog(OpActionEnum.IMPORT.getCode(),Copyrights.class.getSimpleName(),null,"导入版权结束","批量导入版权结束,共导入" + copyrightsDtos.size()+"条记录");


	}


	/**
	 * excel导入参数校验
	 * @param copyrightsDto
	 */
	private void checkImport(CopyrightsDto copyrightsDto) {
		this.commonCheck(copyrightsDto);
		// 检查枚举是否正确映射
		MAssertUtil.notNull(TFEnum.getByCode(copyrightsDto.getContentStatus()),"内容状况填写错误");
		MAssertUtil.notNull(TFEnum.getByCode(copyrightsDto.getSoleFlag()),"是否独家授权填写错误");
		MAssertUtil.notNull(TFEnum.getByCode(copyrightsDto.getSubRightsFlag()),"有无转授权填写错误");
		MAssertUtil.notNull(TFEnum.getByCode(copyrightsDto.getProtocolFlag()),"有无补充协议填写错误");
		MAssertUtil.notNull(TFEnum.getByCode(copyrightsDto.getOriginalCopyrightsFlag()),"有无原始版权填写错误");
//待确认		MAssertUtil.notNull(CopyrightClassEnum.getByCode(copyrightsDto.getCopyrightClass()),"版权权利填写错误");
		MAssertUtil.notNull(BalanceTypeEnum.getByCode(copyrightsDto.getBalanceType()),"结算形式填写错误");
		MAssertUtil.notNull(OnlineStatusEnum.getByCode(copyrightsDto.getOnlineStatus()),"上线状态填写错误");

		// 作品类型(选填)
		String worksType = copyrightsDto.getWorksType();
		if(!StringUtils.isEmpty(worksType)) {
			MAssertUtil.notNull(WorksTypeEnum.getByCode(worksType),"作品类型填写错误");
		}
		// 作品背景(选填,多选)
		String background = copyrightsDto.getBackground();
		if(!StringUtils.isEmpty(background)) {
			String[] split = background.split(",");
			MAssertUtil.notNull(BackgroundEnum.getByCode(split[0]),"作品背景填写错误");
		}
		MAssertUtil.notNull(CopyrightsRangeEnum.getByCode(copyrightsDto.getCopyrightsRange().split(",")[0]),"权限使用范围填写错误");
		MAssertUtil.notNull(UsedPlatformEnum.getByCode(copyrightsDto.getUsedPlatform().split(",")[0]),"使用平台填写错误");
		MAssertUtil.notNull(CopyrightClassEnum.getByCode(copyrightsDto.getCopyrightClass().split(",")[0]),"所授权利填写错误");
		String contractNo = copyrightsDto.getContractNo();

		SupplyContract supplyContract = supplyContractService.findByContractNo(contractNo);
		MAssertUtil.notNull(supplyContract,"查询不到合同信息");
//		String contractId = supplyContract.getId();

//		MAssertUtil.notNull(ContractNoEnum.getByCode(copyrightsDto.getContractNo()),"合同编号填写错误");
	}

	private void doInsertContract(CopyrightsDto copyrightsDto) {

		Copyrights copyrights = new Copyrights();
		BeanUtils.copyProperties(copyrightsDto,copyrights);
		copyrights.setId(this.getNewId());
		String worksStatus = copyrights.getWorksStatus();
		if(StringUtils.isEmpty(worksStatus)) {
			copyrights.setWorksStatus(ValidStatusEnum.VALID.getCode());
		}
		// 生成版权号
		String copyrightsNo = businessCodeGenter.genBusinessCode(BusinessCodeConstant.COPY_RIGHTS_CODE);
		while(!this.checkDuplicationNo(copyrightsNo)) {
			copyrightsNo = businessCodeGenter.genBusinessCode(BusinessCodeConstant.COPY_RIGHTS_CODE);
		}
		copyrights.setCopyrightsNo(copyrightsNo);


//		copyrights.setCopyrightsNo(businessCodeGenter.genBusinessCode(BusinessCodeConstant.COPY_RIGHTS_CODE));
		this.insert(copyrights);

		try {
			String info = BeanCompareUtil.info(BeanCopyUtil.copy(copyrights, ContractRightsDto.class));
			businessLogUtil.recordBusinessLog(OpActionEnum.ADD.getCode(),OpTypeEnum.Copyrights.getCode(),copyrights.getId(),"新增版权:" + copyrights.getCopyrightsNo(),info);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 判断重复
	 * @param copyrightsNo
	 * @return
	 */
	private boolean checkDuplicationNo(String copyrightsNo) {
		Copyrights copyrights = new Copyrights();
		copyrights.setCopyrightsNo(copyrightsNo);
		List<Copyrights> rights = this.find(copyrights);
		if (CollectionUtils.isEmpty(rights)) {
			return true;
		} else {
			return false;
		}
	}

	private void checkDataDup(String id, String worksName,String contractNo) {
		if(!StringUtils.isEmpty(id)) {
			Copyrights oldRights = this.getById(id);
			String oldName = oldRights.getWorksName();
			String oldNo = oldRights.getContractNo();
			if (oldName.equals(worksName) && oldNo.equals(contractNo)) {
				return;
			}
		}
		Copyrights copyrights = this.findByWorksNameAndContractNo(worksName,contractNo);
		if (!ObjectUtils.isEmpty(copyrights)) {
			throw new BusinessException("数据重复添加,已存在该合同编号和合作供应商组合的版权");
		}
	}

	@Override
	public Copyrights findByWorksNameAndContractNo(String worksName, String contractNo) {
		Copyrights copyrights = new Copyrights();
		copyrights.setWorksName(worksName);
		copyrights.setContractNo(contractNo);
		List<Copyrights> copyrightses = this.find(copyrights);
		if (!CollectionUtils.isEmpty(copyrightses)) {
			return copyrightses.get(0);
		}
		return null;
	}

	@Override
	public int insert(Copyrights entity) {
		if (CxtHolder.getUser() != null) {
			entity.setModifier(CxtHolder.getUser().getUserName());
		}
		return super.insert(entity);
	}

	@Override
	public int update(Copyrights entity) {
		if (CxtHolder.getUser() != null) {
			entity.setModifier(CxtHolder.getUser().getUserName());
		}
		return super.update(entity);
	}

	@Override
	public List<Copyrights> findByContractNoAndStatus(String contractNo, String status) {
		Copyrights copyrights = new Copyrights();
		copyrights.setContractNo(contractNo);
		copyrights.setWorksStatus(status);
		return this.find(copyrights);
	}

	@Override
	public List<Copyrights> findNearlyExpire(int month) {
		Date dayBegin = DateUtils.getDayBegin(new Date());
		Date endDate = DateUtils.addMonths(dayBegin, month);
		Copyrights copyrights = new Copyrights();
		copyrights.setWorksStatus(ValidStatusEnum.VALID.getCode());
		copyrights.setEndDate(endDate);
		return this.find(copyrights);
	}

	@Override
	public List<Copyrights> findByCreateById(String userId) {
		if(StringUtils.isEmpty(userId)) {
			return null;
		}
		Copyrights copyrights = new Copyrights();
		copyrights.setCreateById(userId);
		return this.find(copyrights);
	}

    @Override
    public ResultMessage checkCopyrightsDate(String copyrightsNo) {
        ResultMessage result = ResultMessage.error();
        Copyrights copyrights = this.findByCopyrightsNo(copyrightsNo);
        if (copyrights == null) {
            result.setMessage("未查询到版权信息!");
            return result;
        }
        // 判断是否失效
        if (!ValidStatusEnum.VALID.getCode().equals(copyrights.getWorksStatus())) {
            result.setMessage("版权已失效!");
            return result;
        }
        Date endDate = copyrights.getEndDate();
        Date date = new Date();
        int monthDiff = DateUtil.getMonthDiff(endDate, date);
        if (monthDiff < 6) {
            result.setMessage("该版权即将过期，无法进行授权!");
            return result;
        }
        result = ResultMessage.success();
        return result;
    }
}
